package controllers.examples;

import competition.GhostsController;
import controllers.AimPoint;
import core.*;
import core.maze.MazeInterface;
import core.Node;
import core.utilities.Utilities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class PincerTeam implements GhostsController, Constants {

    private static final int off = 100;
    private static final int[][] da = {{off, 0}, {0, off}, {-off, 0}, {0, -off}};

    private final int[] dirs;
    private ArrayList<Node> junctions;
    private MazeInterface maze;

    public PincerTeam() {
        this.dirs = new int[nGhosts];
    }

    public int[] getActions(GameStateInterface gs) {

        if (!gs.getMaze().equals(maze)) setMaze(gs.getMaze());

        Node pac = gs.getPacman().current;
        Set<Node> targets = new HashSet<Node>();
        targets.addAll(junctions);
        for (int i = 0; i < nGhosts; i++) {
            Ghosts ghost = gs.getGhosts()[i];
            Node next;
            ArrayList<Node> possibles = ghost.getPossibles();
            if (possibles.size() == 1) {

                next = possibles.get(0);
            } else {

                Node target = getClosest(targets, new AimPoint(pac.x + da[i][0], pac.y + da[i][1]));


                next = Utilities.getClosest(possibles, target, gs.getMaze());
                targets.remove(target);
            }
            dirs[i] = Utilities.getWrappedDirection(ghost.current, next, gs.getMaze());
        }
        return dirs;
    }

    private void setMaze(MazeInterface maze) {
        this.maze = maze;

        junctions = new ArrayList<Node>();
        for (Node n : maze.getMap()) {
            if (n.adj.size() > 2) {
                junctions.add(n);
            }
        }
    }

    Node getClosest(Collection<Node> nodes, AimPoint p) {
        double best = Double.MAX_VALUE;
        Node sel = null;
        for (Node n : nodes) {
            double s = p.score(null, n);
            if (s < best) {
                best = s;
                sel = n;
            }
        }
        return sel;
    }
}



























































































































































